from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render_to_response
from django.template import RequestContext
from nc_mlpa.mlpa.models import MlpaMpa, MpaArray
from utilities import ensure_proper_name
from forms import *
from lingcod.sharing.utils import can_user_view
from lingcod.common.utils import get_mpa_class, get_array_class

  
'''
Renders a form for caching impact analysis by users
Handles GET requests, as well as 'estimate' and 'process' POST requests
'''
def adminUserAnalysis(request, template="admin/econ_analysis/cache_analysis_by_users.html"):
    from ProcessingTimes import estimate_processing_times
    from MpaAnalysis import process_user_mpas
    if not request.user.is_staff:
        return HttpResponse('You do not have permission to view this feature', status=401)
    if request.method == 'GET':
        form = CacheAnalysisUserForm()
        return render_to_response( template, RequestContext(request, {'form': form, 'complete': False}) )  
    
    form = CacheAnalysisUserForm(request.POST)
    if not form.is_valid():
        return render_to_response( template, RequestContext(request, {'form': form, 'complete': False}) )  
        
    user_ids = form.data.getlist('users')    
    if 'estimate' in request.POST:
        processing_times, total_time = estimate_processing_times(user_ids=user_ids) #returns a dictionary {'user': 'estimated time'}
        return render_to_response( template, RequestContext(request, {'form': form, 'complete': False, 'processing_times': processing_times, 'total_time': total_time}))
    else:
        users = process_user_mpas(user_ids)
        return render_to_response( template, RequestContext(request, {'form': form, 'complete': True, 'users': users}) )  
        
'''
Renders a form for caching impact analysis by user groups
Handles GET requests, as well as 'estimate' and 'process' POST requests
'''
def adminGroupAnalysis(request, template="admin/econ_analysis/cache_analysis_by_user_groups.html"):
    from ProcessingTimes import estimate_processing_times  
    from MpaAnalysis import process_group_mpas
    if not request.user.is_staff:
        return HttpResponse('You do not have permission to view this feature', status=401)
    if request.method == 'GET':
        form = CacheAnalysisGroupForm()
        return render_to_response( template, RequestContext(request, {'form': form}) )  
    
    form = CacheAnalysisGroupForm(request.POST)
    if not form.is_valid():
        return render_to_response( template, RequestContext(request, {'form': form, 'complete': False}) )  
        
    group_ids = form.data.getlist('groups') 
    if 'estimate' in request.POST:
        processing_times, total_time = estimate_processing_times(group_ids=group_ids) #returns a dictionary {'goup': 'estimated time'}
        return render_to_response( template, RequestContext(request, {'form': form, 'complete': False, 'processing_times': processing_times, 'total_time': total_time}))
    else:
        groups = process_group_mpas(group_ids)
        return render_to_response( template, RequestContext(request, {'form': form, 'complete': True, 'groups': groups}) )  

'''
sample view that utilizes the lingcod.asynchronous app with a simple add(x,y) task in econ_analysis.tasks.py 
'''        
def asynchronoustest(request, num1, num2):
    #from nc_mlpa.econ_analysis.tasks import add, named_add
    from nc_mlpa.econ_analysis import tasks
    from lingcod.async.models import URLtoTaskID
    from lingcod.async.ProcessHandler import process_is_running_or_complete, process_is_complete, get_process_result, check_status_or_begin, get_taskid_from_url
    
    #the following conditional is in place for milestone 1.5
    from settings import *
    if ASYNC_IS_DISABLED:
        return HttpResponse("Async is currently disabled.  Change settings.ASYNC_IS_DISABLED to enable asyncadd.")
    
    #extract the url
    url = request.META['PATH_INFO']
    
    #see if this url has been processed already
    if process_is_running_or_complete(url):
        if process_is_complete(url):
            return HttpResponse(str(get_process_result(url)))
        else:
            task_id = get_taskid_from_url(url)
            return HttpResponse('process ' + str(task_id) + ' is still running...')
    #otherwise, process does not exist in cache and we should start the process
    else:
        args = (int(num1), int(num2))
        status_text, task_id = check_status_or_begin(tasks.add, task_args=args, polling_url=url)
        #kwargs = {"x": int(num1), "y": int(num2)}
        #task_id = check_status_or_begin(tasks.named_add, task_kwargs=kwargs, polling_url=url)
        return HttpResponse(status_text + task_id)
    
  
'''
Accessed via named url when user selects a group (Commercial, Recreational Dive, etc) to run analysis on 
'''
def impact_analysis(request, feature_id, group, feature='mpa'):
    from MpaAnalysis import display_mpa_analysis
    from ArrayAnalysis import display_array_analysis
    from AnalysisCache import mpa_cache_is_available_and_current, array_cache_is_available_and_current
    from ProcessingTimes import estimate_time_for_mpa, estimate_time_for_mpas, convert_time_to_text
    from lingcod.async.ProcessHandler import check_status_or_begin
    from settings import *
    from nc_mlpa.econ_analysis import tasks
    group_name = ensure_proper_name(group)
    url = request.META['PATH_INFO']
    if feature == 'mpa':
        #check permissions
        user_can_view, response = can_user_view(get_mpa_class(), feature_id, request.user)
        if not user_can_view:
            return response
        mpa = get_object_or_404(MlpaMpa, pk=feature_id)
        
        #the following allows the application to ignore the async app via a settings variable
        if ASYNC_IS_DISABLED:
            return display_mpa_analysis(request, mpa, group_name)
        
        #display cached results or run mpa analysis in background
        if mpa_cache_is_available_and_current(mpa, group):
            return display_mpa_analysis(request, mpa, group_name)
        else: 
            #package the arguments that should be sent to compile_mpa_results_async
            args = (mpa.id, group)
            #start process or continue to wait for process to complete
            status_text, task_id = check_status_or_begin(tasks.compile_mpa_results_async, task_args=args, polling_url=url)
            #get a time estimate for process completion
            time_estimate = estimate_time_for_mpa(mpa, group) 
            text_time = convert_time_to_text(time_estimate)
            return render_to_response("time_estimate.html", RequestContext( request, {'feature': mpa, 'group': group_name, 'time_estimate': text_time, 'status': status_text} )) 
    else: #must be array
        #check permissions
        user_can_view, response = can_user_view(get_array_class(), feature_id, request.user)
        if not user_can_view:
            return response
        array = get_object_or_404(MpaArray, pk=feature_id)
        mpas = array.mpa_set
        
        #the following allows the application to ignore the async app via a settings variable
        if ASYNC_IS_DISABLED:
            return display_array_analysis(request, group_name, array)
        
        #display cached results or run array analysis in background
        if array_cache_is_available_and_current(array, group):
            return display_array_analysis(request, group_name, array)
        else:
            #package the arguments that should be sent to compile_array_results_async
            args = (array.id, group)
            #start process or continue to wait for process to complete
            status_text, task_id = check_status_or_begin(tasks.compile_array_results_async, task_args=args, polling_url=url)
            #get a time estimate for process completion
            time_estimate = estimate_time_for_mpas(mpas, group) 
            text_time = convert_time_to_text(time_estimate)
            return render_to_response("time_estimate.html", RequestContext( request, {'feature': array, 'group': group_name, 'time_estimate': text_time, 'status': status_text} )) 
        

'''
Accessed via named url when a user selects the View Printable Report link at the bottom of analysis results display
'''
def print_report(request, feature_id, user_group, feature='mpa'): 
    from MpaAnalysis import print_mpa_report
    from ArrayAnalysis import print_array_report
    if feature == 'mpa':
        user_can_view, response = can_user_view(get_mpa_class(), feature_id, request.user)
        if not user_can_view:
            return response
        mpa = get_object_or_404(MlpaMpa, pk=feature_id)
        return print_mpa_report(request, mpa, user_group)
    else: #otherwise, must be an array
        user_can_view, response = can_user_view(get_array_class(), feature_id, request.user)
        if not user_can_view:
            return response
        return print_array_report(request, feature_id, user_group)
